package com.syg.rabbitmq.consumer;

import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.Consumer;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 *
 * <img width="" height="" src="../../../../../resources/picture/work_queue模式.png" alt="work模式默认交换机">
 *     <br/>
 *     <H1>两个消费者是竞争关系，也就是说同一条消息只会发给其中一个消费者</H1>
 *     <br/>
 *     2，工作队列模式（work模式）：
 *     和简单队列模式一样，不过有一点不同，该模式有多个消费者在监听队列。
 *     RabbitMQ会以轮询的方式将消息发给多个消费者确保一条消息只会被一个消费者消费
 *     <br/><br/>
 *     <H1>也就是说该模式与simple模式的代码是一致的,只是多个消费者而已(消费者消费的时候指定队列)</H1>
 */
public class Work_Consumer1 {

    public static void main(String[] args) throws IOException, TimeoutException {
        // 1,创建连接工厂
        ConnectionFactory factory = new ConnectionFactory();

        //2,设置参数  设定连接信息，基操
        factory.setHost("127.0.0.1");
        factory.setPort(5672);  //注意这里写5672，是amqp协议端口
        factory.setUsername("guest");
        factory.setPassword("guest");
        // 为什么这里声明虚拟主机会报错呢？
        factory.setVirtualHost("/");

        // 3,创建连接
        Connection connection = factory.newConnection();
        // 4,创建Channel
        Channel channel = connection.createChannel();


        // 5,创建队列，如果此队列不存在，会自动创建
        /*
                queue:队列名称
                durable:是否持久化,当mq重启之后还在。
                exclusive：是否独占。只能有一个消费者监听这个队列。当connection关闭时,是否删除
                autoDelete：知否自动删除，当没有消费者监听时,删除
         */
        // 如果没有yyds的队列,则会创建一个队列，如果存在则不创建。(如果这里不绑定队列,那么会不会消费到其他队列中的消息？不会，消费的时候指定了队列名)
        // channel.queueDeclare("yyds", false, false, false, null);
        /**
         * basicConsume方法参数如下：
         *      queue  -  消息队列名称，直接指定。
         *      autoAck - 自动应答，消费者从消息队列取出数据后，需要跟服务器进行确认应答，当服务器收到确认后，会自动将消息删除，如果开启自动应答，那么消息发出后会直接删除。
         *      callback  -  回调方法
         */
        Consumer consumer = new DefaultConsumer(channel) {
            /*
             * 回调方法，当收到消息后，会自动执行该方法
             * 1，consumerTag :标识
             * 2，Envelope 获取交换机、路由等信息
             * */
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                // System.out.println("consumerTag=" + consumerTag);
                // System.out.println("Exchange=" + envelope.getExchange());
                // System.out.println("RoutingKey=" + envelope.getRoutingKey());
                // System.out.println("properties=" + properties);
                System.out.println("body=" + new String(body));
            }
        };

        // 消费的时候指定队列名,保证不会消费到其他队列中的消息
        // autoAck 为false,消费者启动时会再次消费之前的数据(可能是使用方式不对)
        channel.basicConsume("work_queue", true, consumer);

    }

}
